#pragma once
#include "../variant.h"
#include "hamiltonfunctor.h"
#include <armadillo>

#ifdef GRAPHENETOOLS_EXPORTS
#ifndef GRAPHENETOOLS_DLL_API
#define GRAPHENETOOLS_DLL_API __declspec(dllexport)
#endif
#else
#ifndef GRAPHENETOOLS_DLL_API
#define GRAPHENETOOLS_DLL_API __declspec(dllimport)
#endif
#endif

class GRAPHENETOOLS_DLL_API ApproximateDoSFunctor
{
	HamiltonFunctor hamFunc;
	arma::vec3 k;
	enum statetypes {
		defaulttype,
		userdefined
	} statetype;
	long states;
	double eta;
	
	static const string wavenumbersymbol;
	static const string statessymbol;
	static const string etasymbol;

	arma::cx_vec alphas;
	arma::vec betas;
public:
	ApproximateDoSFunctor(System* s, const rule::list &opts = rule::list());

protected:
	static arma::cx_vec generateRandomPhaseState(size_t n);
	static void generateTriDiagHamElem(const arma::sp_cx_mat &ham,arma::cx_vec &alphas, arma::vec &betas, const arma::cx_vec &prevstate, arma::cx_vec &currentstate, long currentindex);
	static complex generateGreensResult(const arma::cx_vec &alphas, const arma::vec &betas, const complex &energy, long currentindex, complex &lastGreen);

public:
	complex getGreensFunctionValue(int id, const complex &energy);
	double getDoSValue(int id, double energy);
	arma::mat getDoS(int id, numeric::range energies);
};

